home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume9 / xchg < prev    next >
Encoding:
Text File  |  1990-01-04  |  16.7 KB  |  490 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v09i099: area code corrector
  3. From: john@chinet.chi.il.us (John Mundt)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 9, Issue 99
  7. Submitted-by: john@chinet.chi.il.us (John Mundt)
  8. Archive-name: xchg
  9.  
  10. This little utility will adjust phone numbers in an area code that was
  11. split in two.  Since the most recent is Chicago, the exchange numbers
  12. are included with the -DCHICAGO option. Otherwise, it can be used for
  13. other area codes if the different exchange numbers are placed in two
  14. data files as explained in README.  
  15.  
  16. Compile using cc -O -s -o xchg -DCHICAGO xchg.c /lib/libPW.a
  17.  
  18. Normal usage would be 
  19.     
  20.     xchg -n old_phone_file new_phone_file
  21.  
  22. You use -n if you are in the new area code (708) or -o if you are
  23. in the old area code (312).  It works on ascii files and probably
  24. on some word processer files as well.
  25.  
  26. ---------------------
  27. John Mundt   Teachers' Aide, Inc.  P.O. Box 1666  Highland Park, IL
  28. john@admctr.chi.il.us
  29. ------------------------------cut here----------------------------------
  30. #! /bin/sh
  31. # This is a shell archive.  Remove anything before this line, then unpack
  32. # it by saving it into a file and typing "sh file".  To overwrite existing
  33. # files, type "sh file -c".  You can also feed this as standard input via
  34. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  35. # will see the following message at the end:
  36. #        "End of shell archive."
  37. # Contents:  README xchg.c
  38. # Wrapped by john@chinet on Wed Dec 20 14:38:27 1989
  39. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  40. if test -f 'README' -a "${1}" != "-c" ; then 
  41.   echo shar: Will not clobber existing file \"'README'\"
  42. else
  43. echo shar: Extracting \"'README'\" \(1915 characters\)
  44. sed "s/^X//" >'README' <<'END_OF_FILE'
  45. Xxchg - fix area codes when one is split in two
  46. X
  47. XThis program came into being when area code 312 was split into two
  48. Xwith 708 being the new one.  Lots of phone numbers had to have the
  49. Xcorrect area codes added, and this does that.  It uses two lists of
  50. Xnumbers which are valid for the new and old exchages, namely new.dat
  51. Xand old.dat respectively.  (If compiled with -DCHICAGO, the two tables
  52. Xwill be compiled right into the program and the data files are not
  53. Xneeded.)
  54. X
  55. XThe proper area code is added to all numbers that were in your local
  56. Xarea but no longer are.  Alternatively, you can add the proper area
  57. Xcode to all numbers, regardless of where they fall now.
  58. X
  59. XIt recognizes a number as [^n]nnn-nnnn[^n], [^n]nnn[ )-]nnn-nnnn[^n]
  60. Xwhere n is a digit.  With an area code, 800-555-1212, (800) 555-1212,
  61. Xand (800)555-1212 are all recognized.  Part numbers with patterns that
  62. Xlook like the above could fake it out.  
  63. X
  64. XUsage is 
  65. X
  66. Xxchg [ -dbno ] [ -O old.dat ] [ -N new.dat ] [infile [outfile] ]
  67. X
  68. XStdin input is read and output is to stdout unless file names are
  69. Xspecified on the command line.  
  70. X
  71. X    -n or -o    one must be specified to tell the program
  72. X            if you are now in the <n>ew exchange or the 
  73. X            <o>ld one.  
  74. X
  75. X    -d         put area codes in with a dash rather than using
  76. X            parentheses: 800-555-1212, not (800) 555-1212 
  77. X
  78. X    -b         put in area codes for both the new and the old
  79. X            exchange numbers
  80. X
  81. X    -O        the name of the data on the old exchage
  82. X            numbers.  The first line must have the old
  83. X            exchange area code on it.  Then, one per line
  84. X            are all the exchange prefixes for the
  85. X            exchange.
  86. X
  87. X    -N        the name of the data on the new exchange
  88. X            numbers.  Format as above.
  89. X
  90. XCompile with the following options.  Since regex() and regcmp() are
  91. Xused, the library for same must be incuded.  This is as show below for
  92. XAT&T's SysV3.2.  It is probably somewhere else on different systems.
  93. X
  94. Xcc -O -s -o xchg -DCHICAGO xchg.c /lib/libPW.a
  95. X
  96. END_OF_FILE
  97. if test 1915 -ne `wc -c <'README'`; then
  98.     echo shar: \"'README'\" unpacked with wrong size!
  99. fi
  100. # end of 'README'
  101. fi
  102. if test -f 'xchg.c' -a "${1}" != "-c" ; then 
  103.   echo shar: Will not clobber existing file \"'xchg.c'\"
  104. else
  105. echo shar: Extracting \"'xchg.c'\" \(12418 characters\)
  106. sed "s/^X//" >'xchg.c' <<'END_OF_FILE'
  107. X
  108. X/*
  109. X * This program changes phone numbers from an exchange that has been
  110. X * split into two new area codes.  It adds a (new) prefex in front of
  111. X * all numbers that are outside of the current prefix.
  112. X *
  113. X * It assumes two files called old.dat and new.dat which hold the
  114. X * current prefixes for the old and new area codes, respectively.
  115. X * or if -DCHICAGO, two arrays in this source file are used for the
  116. X * conversion from 312 to 708 area codes respectively.
  117. X *
  118. X * (c) 1989 by
  119. X * John P. Mundt
  120. X * 2737 Port Clinton Road
  121. X * Highland Park, IL 60035
  122. X # (708) 432-9073   <-- now you know why I wrote this :-(
  123. X *
  124. X * mundt@admctr.chi.il.us || john@chinet.chi.il.us
  125. X *
  126. X * Permission is given to use this program in any manner whatsoever as
  127. X * long as it is not used for commercial gain.  Naturally, there are no
  128. X * guarantees to its functionality, accuracy, correctness, insightful-
  129. X * ness, etc.  Flames, compliments, and corrections welcome.
  130. X *
  131. X */
  132. X#include <stdio.h>
  133. X#include <ctype.h>
  134. X#include <string.h>
  135. X#include <search.h>
  136. X
  137. X#ifndef TRUE
  138. X#define TRUE    1
  139. X#define FALSE    0
  140. X#endif
  141. X
  142. X#define CNULL        (char *) 0
  143. X#define BOOLEAN        int
  144. X#define OLDNUMS        "old.dat"
  145. X#define NEWNUMS        "new.dat"
  146. X
  147. Xtypedef struct {
  148. X    char *a_name;        /* the exchange's area code as a string */
  149. X    char *a_file;        /* the file where the exchange numbers are kept */
  150. X    int a_list[1000];    /* the list of valid numbers in the exchage */
  151. X    int a_count;        /* count of how many in a_list */
  152. X} ARRAY;
  153. X
  154. Xvoid exit(),
  155. X     do_it(),
  156. X     strip(),
  157. X     print_it(),
  158. X     make_space(),
  159. X     get_arrays();
  160. X
  161. Xchar *bsearch(),
  162. X     *Strdup();
  163. X
  164. Xint intcmp();
  165. X
  166. X#ifdef CHICAGO
  167. Xint old_ary[] = { 312, 202, 203, 204, 207, 214, 220, 221, 222, 224, 225, 226,
  168. X227, 229, 230, 233, 235, 236, 237, 238, 239, 241, 242, 243, 245, 247, 248,
  169. X252, 254, 261, 262, 263, 264, 265, 266, 267, 268, 269, 271, 273, 274, 275,
  170. X276, 277, 278, 280, 281, 282, 283, 284, 285, 286, 287, 288, 292, 294, 302,
  171. X306, 308, 313, 315, 316, 321, 322, 324, 326, 327, 329, 332, 334, 337, 338,
  172. X341, 342, 346, 347, 348, 353, 363, 368, 372, 374, 375, 376, 378, 379, 380,
  173. X384, 399, 401, 404, 407, 408, 410, 413, 415, 417, 419, 421, 427, 431, 434,
  174. X435, 436, 440, 443, 444, 445, 454, 461, 463, 465, 467, 468, 471, 472, 476,
  175. X477, 478, 483, 486, 487, 488, 489, 493, 502, 504, 507, 508, 509, 514, 521,
  176. X522, 523, 525, 527, 528, 533, 536, 538, 539, 542, 545, 548, 549, 550, 555,
  177. X558, 559, 561, 565, 567, 568, 569, 580, 581, 582, 583, 585, 586, 588, 589,
  178. X591, 592, 601, 602, 604, 606, 607, 608, 609, 613, 616, 618, 621, 622, 624,
  179. X625, 626, 630, 631, 633, 637, 638, 641, 642, 643, 644, 645, 646, 648, 649,
  180. X650, 651, 659, 660, 661, 663, 664, 666, 667, 670, 684, 685, 686, 693, 694,
  181. X701, 702, 703, 704, 707, 712, 714, 715, 716, 718, 721, 722, 723, 725, 726,
  182. X727, 728, 731, 732, 733, 734, 735, 736, 737, 738, 743, 744, 745, 750, 751,
  183. X752, 753, 760, 761, 762, 763, 764, 765, 767, 768, 769, 770, 772, 774, 775,
  184. X776, 777, 778, 779, 781, 782, 783, 784, 785, 786, 787, 791, 792, 793, 794,
  185. X796, 797, 802, 804, 805, 807, 808, 812, 814, 819, 821, 822, 826, 828, 829,
  186. X836, 838, 842, 845, 846, 847, 853, 854, 855, 856, 861, 871, 873, 874, 875,
  187. X876, 878, 880, 881, 883, 886, 889, 890, 899, 901, 902, 903, 906, 907, 908,
  188. X909, 914, 915, 917, 918, 919, 921, 922, 923, 924, 925, 927, 929, 930, 933,
  189. X935, 936, 938, 939, 942, 943, 944, 947, 951, 955, 962, 973, 975, 976, 977,
  190. X978, 984, 987, 988, 989, 992, 993, 994, 995, 996, 997, 0 
  191. X};
  192. X
  193. Xint new_ary[] = { 708, 201, 205, 206, 208, 209, 210,
  194. X213, 215, 216, 218, 223, 228, 231, 232, 234, 240, 244, 246,
  195. X249, 250, 251, 253, 255, 256, 257, 258, 259, 260, 272, 279, 
  196. X289, 290, 291, 293, 295, 296, 297, 298, 299, 301, 303, 304,
  197. X305, 307, 310, 314, 317, 318, 319, 323, 325, 328, 330, 331,
  198. X333, 335, 336, 339, 343, 344, 345, 349, 350, 351, 352, 354,
  199. X355, 356, 357, 358, 359, 360, 361, 362, 364, 365, 366, 367,
  200. X369, 371, 377, 381, 382, 383, 385, 386, 387, 388, 389, 390,
  201. X391, 392, 393, 394, 395, 396, 397, 398, 402, 403, 405, 406,
  202. X409, 412, 416, 418, 420, 422, 423, 424, 425, 426, 428, 429,
  203. X430, 432, 433, 437, 438, 439, 441, 442, 446, 447, 448, 449,
  204. X450, 451, 452, 453, 455, 456, 457, 458, 459, 460, 462, 464,
  205. X466, 469, 470, 473, 474, 475, 479, 480, 481, 482, 484, 485,
  206. X490, 491, 492, 495, 496, 497, 498, 499, 501, 503, 505, 506,
  207. X510, 512, 513, 515, 516, 517, 518, 519, 520, 524, 526, 529,
  208. X530, 531, 532, 534, 535, 537, 540, 541, 543, 544, 546, 547,
  209. X551, 552, 553, 554, 555, 556, 557, 560, 562, 563, 564, 566,
  210. X570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 584, 587,
  211. X590, 591, 593, 594, 595, 596, 597, 598, 599, 603, 605, 612,
  212. X614, 615, 617, 619, 620, 623, 627, 628, 629, 632, 634, 635,
  213. X636, 639, 640, 647, 652, 653, 654, 655, 656, 657, 658, 662,
  214. X665, 668, 669, 671, 672, 673, 674, 675, 676, 677, 678, 679,
  215. X680, 681, 682, 683, 687, 688, 689, 690, 691, 692, 695, 696,
  216. X697, 698, 699, 705, 706, 709, 713, 717, 719, 720, 724, 729,
  217. X730, 739, 740, 741, 742, 746, 747, 748, 749, 754, 755, 756,
  218. X757, 758, 759, 766, 771, 773, 780, 788, 789, 790, 795, 796,
  219. X798, 799, 801, 803, 806, 810, 816, 817, 818, 820, 823, 824,
  220. X825, 827, 830, 831, 832, 833, 834, 835, 837, 839, 840, 841,
  221. X843, 844, 848, 849, 850, 851, 852, 857, 858, 859, 860, 862,
  222. X863, 864, 865, 866, 867, 868, 869, 870, 872, 877, 879, 882,
  223. X884, 885, 887, 888, 891, 892, 893, 894, 895, 896, 897, 898,
  224. X904, 905, 910, 913, 916, 920, 926, 931, 932, 934, 937, 940,
  225. X941, 945, 946, 948, 949, 952, 953, 954, 956, 957, 960, 961,
  226. X963, 964, 965, 966, 967, 968, 969, 971, 972, 974, 976, 979,
  227. X980, 981, 982, 983, 985, 986, 990, 991, 998, 0 };
  228. X#endif
  229. X
  230. XARRAY oldx, newx;
  231. XARRAY *presentx_ptr;            /* the exchange user is now in */
  232. XARRAY *otherx_ptr;                /* exchange s/he ain't in */
  233. XBOOLEAN parens;                    /* do we use parentheses or dashes */
  234. XBOOLEAN do_both;                /* put in both area codes? */
  235. XBOOLEAN start_of_line;            /* horrible kludge */
  236. Xchar *progname;
  237. X
  238. X/*
  239. X * regular expression which locates what are considered phone numbers
  240. X */
  241. Xchar *_re_phone = 
  242. X    "(([^0-9][0-9]{3}){0,1})$0([^0-9]{1,2})$1([0-9]{3}-[0-9]{4})$2[^0-9]";
  243. X
  244. Xmain(argc, argv)
  245. Xint argc;
  246. Xchar **argv;
  247. X{
  248. Xextern int optind, opterr;
  249. Xextern char *optarg;
  250. Xint c;
  251. Xchar buf[BUFSIZ / 2], *re_phone, *regcmp(), *regex();
  252. X    oldx.a_file = OLDNUMS, newx.a_file = NEWNUMS;
  253. X    do_both = FALSE;                /* only add other area code */
  254. X    parens = TRUE;                    /* format (800) rather than 800- */
  255. X    opterr = 1;                        /* lock getopt()'s ? out */
  256. X    presentx_ptr = (ARRAY *) 0;        /* see if it is set later */
  257. X#ifdef CHICAGO
  258. X    while ((c = getopt(argc, argv, "bdon")) != EOF) {
  259. X#else
  260. X    while ((c = getopt(argc, argv, "bdonO:N:")) != EOF) {
  261. X#endif
  262. X        switch(c) {
  263. X        case 'b'    :    do_both = TRUE;            break;
  264. X        case 'o'    :    presentx_ptr = &oldx;    break;
  265. X        case 'n'    :    presentx_ptr = &newx;    break;
  266. X        case 'd'    :    parens = FALSE;            break;
  267. X#ifndef CHICAGO
  268. X        case 'O'    :    oldx.a_file = optarg;    break;
  269. X        case 'N'    :    newx.a_file = optarg;    break;
  270. X#endif
  271. X        case '?'    :    out();                    break;
  272. X        }
  273. X    }
  274. X    if (!presentx_ptr) {            /* which exchage we are in must be known */
  275. X        if (optind >= argc) {        /* if stdin is redirected this won't work */
  276. X            (void)fprintf(stderr, 
  277. X            "Option -o or -n must be set when stdin is redirected\n");
  278. X            exit(1);
  279. X        } else {                    /* so ask which exchange we are in */
  280. X            (void) printf("Are you located in the <o>ld or <n>ew exchange?");
  281. X            (void) scanf("%s", buf);
  282. X            if (*buf == 'o' || *buf == 'O')
  283. X                presentx_ptr = &oldx;
  284. X            else
  285. X                presentx_ptr = &newx;
  286. X        }
  287. X    }
  288. X    otherx_ptr = (presentx_ptr == &oldx) ? &newx : &oldx;
  289. X    if (optind < argc) {        /* input file name listed */
  290. X        if (!freopen(argv[optind], "r", stdin)) {
  291. X            (void)fprintf(stderr, "%s cannot be opened for reading\n",
  292. X                        argv[optind]);
  293. X            exit(1);
  294. X        }
  295. X        if (++optind < argc && !freopen(argv[optind], "r", stdout)) {
  296. X            (void)fprintf(stderr, "%s cannot be opened for reading\n",
  297. X                        argv[optind]);
  298. X            exit(1);
  299. X        }
  300. X    }
  301. X    if (!(re_phone = regcmp(_re_phone, CNULL))) {
  302. X        (void)fprintf(stderr, "%s bad regular expression\n", _re_phone);
  303. X        exit(1);
  304. X    }
  305. X    get_arrays();        /* should've been a look-up table, on hindsight */
  306. X    do_it(re_phone);    /* make the changes */
  307. X    exit(0);
  308. X    /* NOTREACHED */
  309. X}
  310. X
  311. Xvoid do_it(re)
  312. Xchar *re;                            /* our compiled regular expression */
  313. X{
  314. Xchar buf[BUFSIZ * 5], area_code[5], spacer[3], number[9], *ptr, *stop;
  315. Xregister char *start;
  316. Xextern char *__loc1;                /* beginning of match, if any */
  317. X    ptr = buf;                        /* re matches non-number char at ends */
  318. X    *ptr++ = ' ';                    /* this is kludge to make them */
  319. X    while (fgets(ptr, BUFSIZ * 5, stdin)) {
  320. X        start = buf;
  321. X        while (stop = regex(re, start, area_code, spacer, number))  {
  322. X            if (start == buf)
  323. X                start++;
  324. X            if (__loc1 == buf) {    /* phone number at start of line */
  325. X                start_of_line = TRUE;    /* so be sure not to include the */
  326. X                start = ptr;        /* lead fudge character */
  327. X            } else
  328. X                start_of_line = FALSE;
  329. X            while (start < __loc1)
  330. X                (void)putchar(*start++);
  331. X            put_number(area_code, number, spacer);
  332. X            start = --stop;            /* re holds one extra character at end */
  333. X        }                            /* print residual string */
  334. X        (void)printf("%s", (start == buf) ? ptr : start);
  335. X    }
  336. X}
  337. X
  338. Xput_number(ac, number, spacer)
  339. Xchar *ac, *number, *spacer;
  340. X{
  341. Xint val;
  342. X    val = atoi(number);
  343. X    if (!*ac) {                                        /* no area code listed */
  344. X        make_space(spacer);
  345. X        if (bsearch((char *) &val, (char *) otherx_ptr->a_list,
  346. X                    otherx_ptr->a_count, sizeof(int *), intcmp)) {
  347. X            print_it(otherx_ptr->a_name, number, '\0');
  348. X        } else if (do_both == TRUE) {                /* in present exchange */
  349. X            if (bsearch((char *) &val, (char *) presentx_ptr->a_list,
  350. X                        presentx_ptr->a_count, sizeof(int *), intcmp))
  351. X                print_it(presentx_ptr->a_name, number, '\0');
  352. X            else
  353. X                print_it("???", number, '\0');
  354. X        } else                                         /* assume number is */
  355. X            (void)printf("%s", number);                /* in current exchange */
  356. X    } else if (!strcmp(ac + 1, presentx_ptr->a_name)/* matches old or new */
  357. X                || !strcmp(ac + 1, otherx_ptr->a_name)) {
  358. X        if (bsearch((char *) &val, (char *) presentx_ptr->a_list,
  359. X                presentx_ptr->a_count, sizeof(int *), intcmp))
  360. X            print_it(presentx_ptr->a_name, number, *ac);
  361. X        else if (bsearch((char *) &val, (char *) otherx_ptr->a_list,
  362. X                otherx_ptr->a_count, sizeof(int *), intcmp))
  363. X            print_it(otherx_ptr->a_name, number, *ac);
  364. X        else
  365. X            print_it("???", number, *ac);        /* a wrong! number */
  366. X    } else                                         /* different area code */
  367. X        print_it(ac + 1, number, *ac);
  368. X}
  369. X
  370. Xvoid print_it(s1, s2, c)
  371. Xchar *s1, *s2, c;
  372. X{
  373. X    if (c && start_of_line==FALSE && c != '(')    /* no extra parens */
  374. X        (void)putchar(c);
  375. X    (void)printf(parens == TRUE ? "(%s) %s" : "%s-%s", s1, s2);
  376. X}
  377. X
  378. Xintcmp(one, two)
  379. Xint *one, *two;
  380. X{
  381. X    return(*one - *two);
  382. X}
  383. X
  384. X#ifdef CHICAGO
  385. Xvoid get_arrays() 
  386. X{
  387. XARRAY *aptr;
  388. Xint i, *iptr;
  389. Xregister int j;
  390. Xchar buf[10];
  391. X    for (j = i = 0, iptr = old_ary, aptr = &oldx; i < 2; 
  392. X                    iptr = new_ary, aptr = &newx, j = 0, i++) {
  393. X        (void)sprintf(buf, "%03d", *iptr);
  394. X        aptr->a_name = Strdup(buf);
  395. X        while (aptr->a_list[j] = iptr[j + 1])
  396. X            j++;
  397. X        aptr->a_count = j;
  398. X        qsort((char *) aptr->a_list, j, sizeof(int *), intcmp);
  399. X    }
  400. X}
  401. X#else
  402. Xvoid get_arrays() 
  403. X{
  404. XFILE *fp;
  405. Xchar buf[BUFSIZ], *ptr;
  406. XARRAY *aptr;
  407. Xint i;
  408. X    for (i = 0, aptr = &oldx; i < 2; aptr = &newx, i++) {
  409. X        aptr->a_count = -1;
  410. X        if (!(fp = fopen(aptr->a_file, "r"))) {
  411. X            (void)fprintf(stderr, "Unable to open numbers file %s\n", 
  412. X                aptr->a_file);
  413. X            exit(1);
  414. X        }
  415. X        while (fgets(buf, BUFSIZ, fp)) {
  416. X            if (isdigit(*buf)) {
  417. X                if (++aptr->a_count == 0) {        /* get the old/new exchange */
  418. X                    for (ptr = buf; isspace(*ptr++); )
  419. X                        ;                        /* make a clean string */
  420. X                    strip(--ptr);
  421. X                    aptr->a_name = Strdup(ptr);
  422. X                } else if ((aptr->a_list[aptr->a_count - 1] = atoi(buf)) < 100 
  423. X                                || aptr->a_list[aptr->a_count] > 999) {
  424. X                    (void)fprintf(stderr, "Bad numbers in file %s\n", 
  425. X                            aptr->a_file);
  426. X                    exit(1);
  427. X                }
  428. X                aptr->a_list[aptr->a_count] = 0;
  429. X            }
  430. X        }
  431. X        qsort((char *) aptr->a_list, (unsigned) aptr->a_count, 
  432. X                        sizeof(int *), intcmp);
  433. X    }
  434. X}
  435. X#endif
  436. X
  437. Xout() 
  438. X{
  439. X    (void)fprintf(stderr, 
  440. X        "Usage %s: [-bd] [-o -n] [input file [output file] ]\n", progname);
  441. X    exit(1);
  442. X}
  443. X
  444. Xvoid strip(s)
  445. Xchar *s;
  446. X{
  447. Xregister char *ptr = s + strlen(s);
  448. X    while (--ptr >= s && isspace(*ptr))
  449. X        ;
  450. X    *++ptr = '\0';
  451. X}
  452. X
  453. Xvoid make_space(s)
  454. Xchar *s;
  455. X{
  456. X    if (*s && start_of_line == TRUE)    /* remember the kludge */
  457. X        s++;
  458. X    while (*s) {
  459. X        if (*s != '(')
  460. X            (void)putchar(*s);
  461. X        s++;
  462. X    }
  463. X}
  464. X
  465. X/*
  466. X * some systems don't have this, like an AT&T UNIXPC, so...
  467. X */
  468. Xchar *Strdup(s1)
  469. Xchar *s1;
  470. X{
  471. Xchar *s2, *ptr, *malloc();
  472. X        if (!s1)
  473. X                return(CNULL);
  474. X        if (ptr = s2 = malloc((unsigned) strlen(s1) + 1))
  475. X                while (*s2++ = *s1++)
  476. X                        ;
  477. X        return(ptr);
  478. X}
  479. X
  480. END_OF_FILE
  481. if test 12418 -ne `wc -c <'xchg.c'`; then
  482.     echo shar: \"'xchg.c'\" unpacked with wrong size!
  483. fi
  484. # end of 'xchg.c'
  485. fi
  486. echo shar: End of shell archive.
  487. exit 0
  488.  
  489.  
  490.